home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Cafe 3
/
Visual Cafe 3.ISO
/
Vcafe
/
JFC.bin
/
BasicGraphicsUtils.java
< prev
next >
Wrap
Text File
|
1998-06-30
|
20KB
|
645 lines
/*
* @(#)BasicGraphicsUtils.java 1.34 98/02/04
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.plaf.basic;
import com.sun.java.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
/*
* @version 1.34 02/04/98
* @author Hans Muller
*/
public class BasicGraphicsUtils
{
public static final Font controlFont = new Font("Dialog", Font.PLAIN, 12);
public static Color control = Color.lightGray;
public static Color controlShadow = Color.gray;
public static Color controlHighlight = Color.white;
public static Color controlBlack = Color.black;
public static Color controlWhite = Color.white;
public static Color scrollbarTrack = new Color(224, 224, 224);
public static Color toolTip = new Color(255, 255, 225);
private static final Insets GROOVE_INSETS = new Insets(2, 2, 2, 2);
private static final Insets ETCHED_INSETS = new Insets(2, 2, 2, 2);
public static void drawEtchedRect(Graphics g, int x, int y, int w, int h)
{
Color oldColor = g.getColor(); // Make no net change to g
g.translate(x, y);
g.setColor(controlShadow);
g.drawLine(0, 0, w-1, 0); // outer border, top
g.drawLine(0, 1, 0, h-2); // outer border, left
g.setColor(controlBlack);
g.drawLine(1, 1, w-3, 1); // inner border, top
g.drawLine(1, 2, 1, h-3); // inner border, left
g.setColor(controlWhite);
g.drawLine(w-1, 0, w-1, h-1); // outer border, bottom
g.drawLine(0, h-1, w-1, h-1); // outer border, right
g.setColor(control);
g.drawLine(w-2, 1, w-2, h-3); // inner border, right
g.drawLine(1, h-2, w-3, h-2); // inner border, bottom
g.translate(-x, -y);
g.setColor(oldColor);
}
/**
* Returns the amount of space taken up by a border drawn by
* <code>drawEtchedRect()</code>
*
* @return the inset of an etched rect
*/
public static Insets getEtchedInsets() {
return ETCHED_INSETS;
}
public static void drawGroove(Graphics g, int x, int y, int w, int h)
{
Color oldColor = g.getColor(); // Make no net change to g
g.translate(x, y);
g.setColor(controlShadow);
g.drawRect(0, 0, w-2, h-2);
g.setColor(controlWhite);
g.drawLine(1, h-3, 1, 1);
g.drawLine(1, 1, w-3, 1);
g.drawLine(0, h-1, w-1, h-1);
g.drawLine(w-1, h-1, w-1, 0);
g.translate(-x, -y);
g.setColor(oldColor);
}
/**
* Returns the amount of space taken up by a border drawn by
* <code>drawGroove()</code>
*
* @return the inset of a groove border
*/
public static Insets getGrooveInsets() {
return GROOVE_INSETS;
}
public static void drawBezel(Graphics g, int x, int y, int w, int h, boolean isPressed, boolean isDefault)
{
Color oldColor = g.getColor(); // Make no net change to g
g.translate(x, y);
if (isPressed) {
if (isDefault) {
g.setColor(controlBlack); // outer border
g.drawRect(0, 0, w-1, h-1);
}
g.setColor(controlShadow); // inner border
g.drawRect(1, 1, w-3, h-3);
}
else {
if (isDefault) {
g.setColor(controlBlack); // outer border
g.drawRect(0, 0, w-1, h-1);
g.setColor(controlHighlight); // inner 3D border
g.drawLine(1, 1, 1, h-3);
g.drawLine(2, 1, w-4, 1);
g.setColor(controlShadow);
g.drawLine(2, h-3, w-3, h-3);
g.drawLine(w-3, 1, w-3, h-4);
g.setColor(Color.black); // black drop shadow __|
g.drawLine(1, h-2, w-2, h-2);
g.drawLine(w-2, h-2, w-2, 1);
}
else {
g.setColor(controlHighlight); // inner 3D border
g.drawLine(0, 0, 0, h-1);
g.drawLine(1, 0, w-3, 0);
g.setColor(controlShadow);
g.drawLine(1, h-2, w-2, h-2);
g.drawLine(w-2, 0, w-2, h-3);
g.setColor(Color.black); // black drop shadow __|
g.drawLine(0, h-1, w-1, h-1);
g.drawLine(w-1, h-1, w-1, 0);
}
g.translate(-x, -y);
g.setColor(oldColor);
}
}
public static void drawLoweredBezel(Graphics g, int x, int y, int w, int h) {
g.setColor(controlBlack); // inner 3D border
g.drawLine(0, 0, 0, h-1);
g.drawLine(1, 0, w-3, 0);
g.setColor(controlShadow);
g.drawLine(1, 1, 1, h-2);
g.drawLine(1, 1, w-3, 1);
g.setColor(controlHighlight);
g.drawLine(0, h-1, w-1, h-1);
g.drawLine(w-1, h-1, w-1, 0);
}
/** Draw a string with the graphics g at location (x,y) just like g.drawString() would.
* The first occurence of underlineChar in text will be underlined. The matching is
* not case sensitive.
*/
public static void drawString(Graphics g,String text,int underlinedChar,int x,int y) {
char b[] = new char[1];
String s;
char lc,uc;
int index=-1,lci,uci;
if(underlinedChar != '\0') {
b[0] = (char)underlinedChar;
s = new String(b).toUpperCase();
uc = s.charAt(0);
s = new String(b).toLowerCase();
lc = s.charAt(0);
uci = text.indexOf(uc);
lci = text.indexOf(lc);
if(uci == -1)
index = lci;
else if(lci == -1)
index = uci;
else
index = (lci < uci) ? lci : uci;
}
g.drawString(text,x,y);
if(index != -1) {
FontMetrics fm = g.getFontMetrics();
Rectangle underlineRect = new Rectangle();
underlineRect.x = x + fm.stringWidth(text.substring(0,index));
underlineRect.y = y;
underlineRect.width = fm.charWidth(text.charAt(index));
underlineRect.height = 1;
g.fillRect(underlineRect.x,underlineRect.y + fm.getDescent() - 1,
underlineRect.width,underlineRect.height);
}
}
public static void drawDashedRect(Graphics g,int x,int y,int width,int height) {
int vx,vy;
// draw upper and lower horizontal dashes
for (vx = x; vx < (x + width); vx+=2) {
g.drawLine(vx, y, vx, y);
g.drawLine(vx, y + height-1, vx, y + height-1);
}
// draw left and right vertical dashes
for (vy = y; vy < (y + height); vy+=2) {
g.drawLine(x, vy, x, vy);
g.drawLine(x+width-1, vy, x + width-1, vy);
}
}
public static void paintMenuItem(Graphics g, JComponent c,
Icon checkIcon, Icon arrowIcon,
Color background, Color foreground,
int defaultTextIconGap) {
JMenuItem b = (JMenuItem) c;
ButtonModel model = b.getModel();
Dimension size = b.getSize();
Insets i = c.getInsets();
Rectangle viewRect = new Rectangle(size);
viewRect.x += i.left;
viewRect.y += i.top;
viewRect.width -= (i.right + viewRect.x);
viewRect.height -= (i.bottom + viewRect.y);
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Rectangle acceleratorRect = new Rectangle();
Rectangle checkRect = new Rectangle();
Rectangle arrowRect = new Rectangle();
Font holdf = g.getFont();
Font f = c.getFont();
g.setFont( f );
FontMetrics fm = g.getFontMetrics( f );
FontMetrics fmAccel = g.getFontMetrics( UIManager.getFont("MenuItem.acceleratorFont") );
// Paint background
Color holdc = g.getColor();
if(c.isOpaque()) {
if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
g.setColor(background);
g.fillRect(0,0, size.width, size.height);
} else {
g.setColor(b.getBackground());
g.fillRect(0,0, size.width, size.height);
}
g.setColor(holdc);
}
// get Accelerator text
KeyStroke accelerator = b.getAccelerator();
String acceleratorText = "";
if (accelerator != null) {
int modifiers = accelerator.getModifiers();
if (modifiers > 0) {
acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
acceleratorText += "+";
}
acceleratorText += KeyEvent.getKeyText(accelerator.getKeyCode());
}
// layout the text and icon
String text = layoutMenuItem(
fm, b.getText(), fmAccel, acceleratorText, b.getIcon(),
checkIcon, arrowIcon,
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect, acceleratorRect,
checkRect, arrowRect,
b.getText() == null ? 0 : defaultTextIconGap,
defaultTextIconGap
);
// Paint the Check
if (checkIcon != null) {
if(model.isArmed() || (c instanceof JMenu && model.isSelected())) {
g.setColor(foreground);
} else {
g.setColor(b.getForeground());
}
checkIcon.paintIcon(c, g, checkRect.x, checkRect.y);
g.setColor(holdc);
}
// Paint the Icon
if(b.getIcon() != null) {
Icon icon;
if(!model.isEnabled()) {
icon = (Icon) b.getDisabledIcon();
} else if(model.isPressed() && model.isArmed()) {
icon = (Icon) b.getPressedIcon();
if(icon == null) {
// Use default icon
icon = (Icon) b.getIcon();
}
} else {
icon = (Icon) b.getIcon();
}
icon.paintIcon(c, g, iconRect.x, iconRect.y);
}
// Draw the Text
if(text != null && !text.equals("")) {
if(!model.isEnabled()) {
// *** paint the text disabled
if ( UIManager.get("MenuItem.disabledForeground") instanceof Color )
{
g.setColor( UIManager.getColor("MenuItem.disabledForeground") );
BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
textRect.x, textRect.y + fm.getAscent());
}
else
{
g.setColor(b.getBackground().brighter());
BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
textRect.x, textRect.y + fm.getAscent());
g.setColor(b.getBackground().darker());
BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
textRect.x - 1, textRect.y + fm.getAscent() - 1);
}
} else {
// *** paint the text normally
if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
g.setColor(foreground);
} else {
g.setColor(b.getForeground());
}
BasicGraphicsUtils.drawString(g,text,
model.getMnemonic(),
textRect.x,
textRect.y + fm.getAscent());
}
}
// Draw the Accelerator Text
if(acceleratorText != null && !acceleratorText.equals("")) {
g.setFont( UIManager.getFont("MenuItem.acceleratorFont") );
if(!model.isEnabled()) {
// *** paint the acceleratorText disabled
if ( UIManager.get("MenuItem.disabledForeground") instanceof Color )
{
g.setColor( UIManager.getColor("MenuItem.disabledForeground") );
BasicGraphicsUtils.drawString(g,acceleratorText,model.getMnemonic(),
acceleratorRect.x, acceleratorRect.y + fm.getAscent());
}
else
{
g.setColor(b.getBackground().brighter());
BasicGraphicsUtils.drawString(g,acceleratorText,model.getMnemonic(),
acceleratorRect.x, acceleratorRect.y + fm.getAscent());
g.setColor(b.getBackground().darker());
BasicGraphicsUtils.drawString(g,acceleratorText,model.getMnemonic(),
acceleratorRect.x - 1, acceleratorRect.y + fm.getAscent() - 1);
}
} else {
// *** paint the acceleratorText normally
if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
g.setColor( UIManager.getColor("MenuItem.acceleratorPressedForeground") );
} else {
g.setColor( UIManager.getColor("MenuItem.acceleratorForeground") );
}
BasicGraphicsUtils.drawString(g,acceleratorText,
model.getMnemonic(),
acceleratorRect.x,
acceleratorRect.y + fm.getAscent());
}
}
// Paint the Arrow
if (arrowIcon != null) {
if(model.isArmed() || (c instanceof JMenu &&model.isSelected()))
g.setColor(foreground);
if( !(b.getParent() instanceof JMenuBar) )
arrowIcon.paintIcon(c, g, arrowRect.x, arrowRect.y);
}
g.setColor(holdc);
g.setFont(holdf);
}
public static Dimension getPreferredButtonSize(AbstractButton b, int textIconGap)
{
if(b.getComponentCount() > 0) {
return null;
}
Icon icon = (Icon) b.getIcon();
String text = b.getText();
Font font = b.getFont();
FontMetrics fm = b.getToolkit().getFontMetrics(font);
Rectangle iconR = new Rectangle();
Rectangle textR = new Rectangle();
Rectangle viewR = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
SwingUtilities.layoutCompoundLabel(
fm, text, icon,
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewR, iconR, textR, (text == null ? 0 : textIconGap)
);
/* The preferred size of the button is the size of
* the text and icon rectangles plus the buttons insets.
*/
Rectangle r = iconR.union(textR);
Insets insets = b.getInsets();
r.width += insets.left + insets.right;
r.height += insets.top + insets.bottom;
/* Ensure that the width and height of the button is odd,
* to allow for the focus line.
*/
if(r.width % 2 == 0) { r.width += 1; }
if(r.height % 2 == 0) { r.height += 1; }
return r.getSize();
}
/**
* Compute and return the location of the icons origin, the
* location of origin of the text baseline, and a possibly clipped
* version of the compound labels string. Locations are computed
* relative to the viewR rectangle.
*/
public static String layoutMenuItem(
FontMetrics fm,
String text,
FontMetrics fmAccel,
String acceleratorText,
Icon icon,
Icon checkIcon,
Icon arrowIcon,
int verticalAlignment,
int horizontalAlignment,
int verticalTextPosition,
int horizontalTextPosition,
Rectangle viewR,
Rectangle iconR,
Rectangle textR,
Rectangle acceleratorR,
Rectangle checkIconR,
Rectangle arrowIconR,
int textIconGap,
int menuItemGap
)
{
SwingUtilities.layoutCompoundLabel(fm, text, icon, verticalAlignment,
horizontalAlignment, verticalTextPosition,
horizontalTextPosition, viewR, iconR, textR,
textIconGap);
/* Initialize the acceelratorText bounds rectangle textR. If a null
* or and empty String was specified we substitute "" here
* and use 0,0,0,0 for acceleratorTextR.
*/
boolean acceleratorTextIsEmpty = (acceleratorText == null) ||
acceleratorText.equals("");
if (acceleratorTextIsEmpty) {
acceleratorR.width = acceleratorR.height = 0;
acceleratorText = "";
}
else {
acceleratorR.width = SwingUtilities.computeStringWidth( fmAccel, acceleratorText );
acceleratorR.height = fmAccel.getHeight();
}
/* Initialize the checkIcon bounds rectangle checkIconR.
*/
if (checkIcon != null) {
checkIconR.width = checkIcon.getIconWidth();
checkIconR.height = checkIcon.getIconHeight();
}
else {
checkIconR.width = checkIconR.height = 0;
}
/* Initialize the arrowIcon bounds rectangle arrowIconR.
*/
if (arrowIcon != null) {
arrowIconR.width = arrowIcon.getIconWidth();
arrowIconR.height = arrowIcon.getIconHeight();
}
else {
arrowIconR.width = arrowIconR.height = 0;
}
textR.x += checkIconR.width + menuItemGap;
iconR.x += checkIconR.width + menuItemGap;
Rectangle labelR = iconR.union(textR);
// Position the Accelerator text rect
acceleratorR.x += (viewR.width - arrowIconR.width -
menuItemGap - acceleratorR.width);
acceleratorR.y = viewR.y + (viewR.height/2) - (acceleratorR.height/2);
arrowIconR.x += (viewR.width - arrowIconR.width);
arrowIconR.y = viewR.y + (labelR.height/2) - (arrowIconR.height/2);
checkIconR.y = viewR.y + (labelR.height/2) - (checkIconR.height/2);
checkIconR.x += viewR.x;
/*
System.out.println("Layout: v=" +viewR+" c="+checkIconR+" i="+
iconR+" t="+textR+" acc="+acceleratorR+" a="+arrowIconR);
*/
return text;
}
public static Dimension getPreferredMenuItemSize(JComponent c,
Icon checkIcon,
Icon arrowIcon,
int defaultTextIconGap) {
JMenuItem b = (JMenuItem) c;
Icon icon = (Icon) b.getIcon();
String text = b.getText();
KeyStroke accelerator = b.getAccelerator();
String acceleratorText = "";
if (accelerator != null) {
int modifiers = accelerator.getModifiers();
if (modifiers > 0) {
acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
acceleratorText += "+";
}
acceleratorText += KeyEvent.getKeyText(accelerator.getKeyCode());
}
Font font = b.getFont();
FontMetrics fm = b.getToolkit().getFontMetrics(font);
FontMetrics fmAccel = b.getToolkit().getFontMetrics( UIManager.getFont("MenuItem.acceleratorFont") );
Rectangle iconR = new Rectangle();
Rectangle textR = new Rectangle();
Rectangle acceleratorR = new Rectangle();
Rectangle checkIconR = new Rectangle();
Rectangle arrowIconR = new Rectangle();
Rectangle viewR = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
layoutMenuItem(
fm, text, fmAccel, acceleratorText, icon, checkIcon, arrowIcon,
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewR, iconR, textR, acceleratorR, checkIconR, arrowIconR,
text == null ? 0 : defaultTextIconGap,
defaultTextIconGap
);
// find the union of the icon and text rects
Rectangle r = iconR.union(textR);
// Add in the accelerator
boolean acceleratorTextIsEmpty = (acceleratorText == null) ||
acceleratorText.equals("");
if (!acceleratorTextIsEmpty) {
r.width += acceleratorR.width;
r.width += 7*defaultTextIconGap;
}
// Add in the checkIcon
r.width += checkIconR.width;
r.width += 2*defaultTextIconGap;
// Add in the arrowIcon
r.width += 2*defaultTextIconGap;
r.width += arrowIconR.width;
Insets insets = b.getInsets();
r.width += insets.left + insets.right;
r.height += insets.top + insets.bottom;
// if the width is even, bump it up one. This is critical
// for the focus dash line to draw properly
if(r.width%2 == 0) {
r.width++;
}
// if the height is even, bump it up one. This is critical
// for the text to center properly
if(r.height%2 == 0) {
r.height++;
}
return r.getSize();
}
}